package com.shuyun.hystrix.dynamic.spi;

import cn.hutool.core.convert.Convert;
import com.netflix.hystrix.strategy.properties.HystrixDynamicProperty;
import com.shuyun.hystrix.dynamic.config.ConfigManager;
import com.shuyun.hystrix.dynamic.config.PropertyItem;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 参考：https://mp.weixin.qq.com/s/jA_hvMgt7VmkHWjavAax_Q
 * @author: shuai.chen@shuyun.com
 * @date: 2023/1/17 2:34 PM
 */
public class CustomDynamicProperty<T> implements HystrixDynamicProperty<T>, PropertyObserver {

    protected final String name;
    protected final T defaultValue;
    protected List<Runnable> callbacks;

    protected CustomDynamicProperty(String propName, T defaultValue) {
        this.name = propName;
        this.defaultValue = defaultValue;

        PropertyObserverManager.add(this);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void addCallback(Runnable callback) {
        if (callbacks == null)
            callbacks = new ArrayList<>(1);
        this.callbacks.add(callback);
    }

    @Override
    public String keyName() {
        return name;
    }

    @Override
    public void update(PropertyItem item) {
        if(getName().equals(item.getName())) {
            for(Runnable r : callbacks) {
                r.run();
            }
        }
    }

    @Override
    public T get() {
        return defaultValue;
    }

    protected static class StringDynamicProperty extends CustomDynamicProperty<String> {
        protected StringDynamicProperty(String propName, String defaultValue) {
            super(propName, defaultValue);
        }

        @Override
        public String get() {
            return ConfigManager.getString(name, defaultValue);
        }
    }

    protected static class IntegerDynamicProperty extends CustomDynamicProperty<Integer> {
        protected IntegerDynamicProperty(String propName, Integer defaultValue) {
            super(propName, defaultValue);
        }

        @Override
        public Integer get() {
            String configValue = Convert.toStr(ConfigManager.get(name));
            if(StringUtils.isNotEmpty(configValue)) {
                return Integer.valueOf(configValue);
            }
            return defaultValue;
        }
    }

    protected static class LongDynamicProperty extends CustomDynamicProperty<Long> {
        protected LongDynamicProperty(String propName, Long defaultValue) {
            super(propName, defaultValue);
        }

        @Override
        public Long get() {
            String configValue =  Convert.toStr(ConfigManager.get(name));
            if(StringUtils.isNotEmpty(configValue)) {
                return Long.valueOf(configValue);
            }
            return defaultValue;
        }
    }

    protected static class BooleanDynamicProperty extends CustomDynamicProperty<Boolean> {
        protected BooleanDynamicProperty(String propName, Boolean defaultValue) {
            super(propName, defaultValue);
        }

        @Override
        public Boolean get() {
            String configValue =  Convert.toStr(ConfigManager.get(name));
            if(StringUtils.isNotEmpty(configValue)) {
                return Boolean.valueOf(configValue);
            }
            return defaultValue;
        }
    }

}
